"""
临时文件管理器
统一管理项目中的临时文件，确保及时清理
"""

import os
import glob
import atexit
from pathlib import Path
from typing import List, Set
from datetime import datetime, timedelta

from .logger import get_logger


class TempFileManager:
    """临时文件管理器（单例模式）"""
    
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialized = False
        return cls._instance
    
    def __init__(self):
        """初始化临时文件管理器"""
        if self._initialized:
            return
        
        self.logger = get_logger()
        
        # 项目根目录
        self.project_root = Path(__file__).parent.parent.parent
        
        # 临时文件目录
        self.temp_dirs = {
            'audio': self.project_root / "temp" / "audio",
            'cache': self.project_root / "temp" / "cache",
            'logs_temp': self.project_root / "temp" / "logs"
        }
        
        # 跟踪的临时文件
        self.tracked_files: Set[Path] = set()
        
        # 创建临时目录
        for temp_dir in self.temp_dirs.values():
            temp_dir.mkdir(parents=True, exist_ok=True)
        
        # 注册退出时清理
        atexit.register(self.cleanup_all)
        
        self._initialized = True
        self.logger.debug("临时文件管理器初始化完成")
    
    def get_temp_dir(self, category: str = 'audio') -> Path:
        """
        获取临时目录
        
        Args:
            category: 类别 (audio, cache, logs_temp)
            
        Returns:
            临时目录路径
        """
        if category not in self.temp_dirs:
            category = 'audio'
        return self.temp_dirs[category]
    
    def track_file(self, file_path: Path):
        """
        跟踪临时文件
        
        Args:
            file_path: 文件路径
        """
        self.tracked_files.add(file_path)
    
    def untrack_file(self, file_path: Path):
        """
        取消跟踪文件
        
        Args:
            file_path: 文件路径
        """
        self.tracked_files.discard(file_path)
    
    def cleanup_file(self, file_path: Path) -> bool:
        """
        清理单个文件
        
        Args:
            file_path: 文件路径
            
        Returns:
            是否成功清理
        """
        try:
            if file_path.exists():
                os.unlink(file_path)
                self.tracked_files.discard(file_path)
                self.logger.debug(f"清理临时文件: {file_path.name}")
                return True
        except Exception as e:
            self.logger.warning(f"清理文件失败 {file_path}: {e}")
        return False
    
    def cleanup_pattern(self, directory: Path, pattern: str) -> int:
        """
        按模式清理文件
        
        Args:
            directory: 目录
            pattern: 文件模式（如 "*.wav"）
            
        Returns:
            清理的文件数量
        """
        count = 0
        try:
            files = glob.glob(str(directory / pattern))
            for file_path in files:
                try:
                    os.unlink(file_path)
                    count += 1
                except Exception as e:
                    self.logger.warning(f"删除文件失败 {file_path}: {e}")
            
            if count > 0:
                self.logger.debug(f"清理了 {count} 个文件 ({pattern})")
        except Exception as e:
            self.logger.error(f"清理文件模式失败 {pattern}: {e}")
        
        return count
    
    def cleanup_old_files(self, directory: Path, max_age_hours: int = 24) -> int:
        """
        清理超过指定时间的文件
        
        Args:
            directory: 目录
            max_age_hours: 最大保留时间（小时）
            
        Returns:
            清理的文件数量
        """
        count = 0
        try:
            if not directory.exists():
                return 0
            
            cutoff_time = datetime.now() - timedelta(hours=max_age_hours)
            
            for file_path in directory.iterdir():
                if file_path.is_file():
                    try:
                        file_mtime = datetime.fromtimestamp(file_path.stat().st_mtime)
                        if file_mtime < cutoff_time:
                            os.unlink(file_path)
                            count += 1
                            self.logger.debug(f"清理过期文件: {file_path.name}")
                    except Exception as e:
                        self.logger.warning(f"清理过期文件失败 {file_path}: {e}")
        except Exception as e:
            self.logger.error(f"清理过期文件失败: {e}")
        
        return count
    
    def cleanup_category(self, category: str) -> int:
        """
        清理指定类别的所有临时文件
        
        Args:
            category: 类别名称
            
        Returns:
            清理的文件数量
        """
        if category not in self.temp_dirs:
            return 0
        
        temp_dir = self.temp_dirs[category]
        
        # 根据类别清理不同类型的文件
        patterns = {
            'audio': ['tts_*.wav', '*.mp3', '*.tmp'],
            'cache': ['*.cache', '*.tmp'],
            'logs_temp': ['*.log.tmp']
        }
        
        total_count = 0
        for pattern in patterns.get(category, ['*.tmp']):
            total_count += self.cleanup_pattern(temp_dir, pattern)
        
        return total_count
    
    def cleanup_all(self):
        """清理所有临时文件"""
        self.logger.info("开始清理所有临时文件...")
        
        total_count = 0
        
        # 清理跟踪的文件
        for file_path in list(self.tracked_files):
            if self.cleanup_file(file_path):
                total_count += 1
        
        # 清理各个类别
        for category in self.temp_dirs.keys():
            count = self.cleanup_category(category)
            total_count += count
        
        if total_count > 0:
            self.logger.info(f"✓ 清理了 {total_count} 个临时文件")
        else:
            self.logger.debug("没有需要清理的临时文件")
    
    def get_temp_file_stats(self) -> dict:
        """
        获取临时文件统计信息
        
        Returns:
            统计信息字典
        """
        stats = {
            'total_files': 0,
            'total_size': 0,
            'categories': {}
        }
        
        for category, temp_dir in self.temp_dirs.items():
            if temp_dir.exists():
                files = list(temp_dir.glob('*'))
                file_count = len([f for f in files if f.is_file()])
                total_size = sum(f.stat().st_size for f in files if f.is_file())
                
                stats['categories'][category] = {
                    'files': file_count,
                    'size': total_size
                }
                
                stats['total_files'] += file_count
                stats['total_size'] += total_size
        
        return stats


# 全局实例
_temp_file_manager = None


def get_temp_file_manager() -> TempFileManager:
    """
    获取临时文件管理器单例
    
    Returns:
        TempFileManager实例
    """
    global _temp_file_manager
    if _temp_file_manager is None:
        _temp_file_manager = TempFileManager()
    return _temp_file_manager
